{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+}
{$M 16384,0,655360}
Program Compiler;

Uses Crt,Dos;

Const MAX_WORD_ANALIZE=21; {Количество зарезервированных идентификаторов}
      MAX_BUFFER=4096; {Максимальный размр буфера}
      MAX_VARIABLE=400; {Максимальное количество переменных}
      Digits:set of char=['0'..'9']; {Используемые числа}
      Liters:set of char=['A'..'Z']; {Используемые литеры}
      Symbol:set of char=[' ',#10,#13,'+','-','*','/',':','.',';','=','[',']','(',')','<','>','"','!','|',','];
      Word_Analize:array [1..MAX_WORD_ANALIZE] of string[16]=
        ('WHILE','FOR','IF','BEGIN','END','WRITE','READ',
         'DEFINE','SHL','SHR','XOR','OR','AND','NEWLINE','REPEAT','UNTIL',
         'GOTOXY','CLRSCR','DO','TO','THEN');
      TypesVar:array[1..4]of record
                               NameType:String[7];
                               SizeType:byte;
                               ArifType:boolean;
                             end=((NameType:'INTEGER'; SizeType:2; ArifType:true),
                                  (NameType:'WORD';    SizeType:2; ArifType:true),
                                  (NameType:'BYTE';    SizeType:1; ArifType:true),
                                  (NameType:'CHAR';    SizeType:1; ArifType:false));

Type VarMem=Record
              NameVar:string[20]; {Имя переменной}
              PointVar:Word; {Указатель в буфере данных}
              SizeVar:Word; {Размер переменной}
              SizeType:Word; {Размер переменной}
              TypeVar:string[7]; {Тип переменной}
              Arifmetic:Boolean; {Применимы арифметические операции или нет}
            End;
     Pointer=Record
               Position:word; {Позиция подстановки}
               PosPerexod:word; {Позиция перехода}
               Length:Byte; {0 На данные переход
                             1 На код
                             Расчет смещения}
             End;

Var Stack:Array [1..2048] of Word; {Стек программы}
    Data:Array [0..MAX_BUFFER] of Byte; {Данные программы}
    Code:Array [0..MAX_BUFFER] of Byte; {Буфер кода}
    InpStr:array[0..MAX_BUFFER]of char; {Буфер считанного файла}
    AnaStr:array[0..MAX_BUFFER]of char; {Буфер обработанной строки}
    OutStr:array[0..MAX_BUFFER]of byte; {Выходной COM файл}
    PointVar:array[0..MAX_BUFFER] of Pointer;

    PositionVarPoint:word; {Позиция переходов}

    PositionRecord:word; {Позиция записи в файл OutStr}
    PositionRead:word; {Позиция чтения программы InpStr}
    PositionData:word; {Позиция в данных Data}
    PositionCode:word; {Позиция в коде Code}
    PositionStack:word; {Позиция в коде Stack}

    VarMemory:Array [1..MAX_VARIABLE] of VarMem; {Таблица переменных}
    NewVarPoint:word; {Указывает на массив переменных}

    i,j,k:Integer; {Временные переменные}
    flag1,flag2:Boolean;

    DescriptFile:File; {Дескриптор файла}
    SizeFile:Word; {Размер файла}
    FileInput,FileOutput:string; {Имя входного и выходного файла}

    LengthFile:word; {Переменная длины строки}
    StartProg:boolean; {Признак начала программы}
    BeginOpred:Integer;
    BeginTemp:word;

    Shift:word; {Сдвиг в Com файле}
    Linenews:word; {Указатель на перевод курсора}
    Charnews:Word; {Указатель на печатаемый символ}
    WrtNum:word; {Указатель на процедуру печати числа}
    BuffNum:word; {Указатель на буффер печати числа}
    ReadNum:word; {Указатель на процедуру перевода строки в число}
    BuffRead:word; {Указатель на буфер чтения}

    GotoPos:word; {Указатель на процедуру перевода курсора}
    ClrPos:word; {Указатель на процедуру очистки экрана}

    IdentTemp:string;

{Function UpperCase(c:char):char; {Функция перевода регистров}
{  Begin
    if (c in ['a'..'z']) and flag then c:=chr(ord(c)-32);
    UpperCase:=c;
  End;}

Procedure  ProcE;forward;
Procedure  ProcT;forward;
Procedure  ProcF;forward;

Procedure Initialization;
  Begin
    PositionRecord:=0; PositionRead:=0; PositionData:=0; PositionCode:=0;
    PositionStack:=1; NewVarPoint:=1; StartProg:=False; BeginOpred:=0; BeginTemp:=0;
    LengthFile:=0; Shift:=$100+3; Linenews:=0; WrtNum:=0; PositionVarPoint:=0;
    Charnews:=0; ReadNum:=0; BuffRead:=0; GotoPos:=0;
  End;

Procedure Scaner; {Процедура удаления лишних символов}
  Begin
    For i:=1 to MAX_BUFFER do AnaStr[i]:=chr(0);
    i:=0; j:=0; flag1:=false;
    While i<SizeFile do
      Begin
        Case InpStr[i] of
          ' ': While (InpStr[i+1]=' ') and not(flag1) do inc(i);
          '{': While InpStr[i]<>'}' do inc(i);
          '"': flag1:=not(flag1);
        end;
        if not(InpStr[i] in ['{','}']) and not(flag1) then
          Begin AnaStr[j]:=UpCase(InpStr[i]); inc(j); inc(LengthFile); End
         Else
          Begin if not(InpStr[i] in ['{','}']) then Begin AnaStr[j]:=InpStr[i]; inc(j); inc(LengthFile); End; End;
        inc(i);
      End;
    i:=0; flag1:=true;
    While i<LengthFile do {Убирание лишних пробелов}
      Begin
        if AnaStr[i] in [#10,#13,'+','-','*','/',':','.',';','=','[',']','(',')','<','>','"'] then
          Begin
            if AnaStr[i]='"' then
              flag1:=not(flag1);
            if flag1 then
              begin
                if (AnaStr[i-1]=' ') and (AnaStr[i+1]=' ') then
                  Begin
                    for j:=i-1 to LengthFile do AnaStr[j]:=AnaStr[j+1]; dec(LengthFile);
                    for j:=i to LengthFile do AnaStr[j]:=AnaStr[j+1]; dec(LengthFile);
                    dec(i);
                    Continue;
                  End;
                if (AnaStr[i-1]=' ') and (AnaStr[i+1]<>' ') and (AnaStr[i]<>'"') then
                  Begin for j:=i-1 to LengthFile do AnaStr[j]:=AnaStr[j+1]; dec(LengthFile); Continue; End
                 Else
                  if (AnaStr[i+1]=' ') and (AnaStr[i-1]<>' ') then
                    Begin for j:=i+1 to LengthFile do AnaStr[j]:=AnaStr[j+1]; dec(LengthFile); Continue; End;
              End;
          End;
        inc(i);
      End;
  End;

{Function SizeofOutputFile:word; {Вычисление длины записываемого файла}
{  Var len:word;
  Begin
    len:=0;
    for i:=1 to MAX_BUFFER do if AnaStr[i]<>chr(0) then inc(len);
    SizeofOutputFile:=len;
  End;}

Function CutWord:string; {Вырезает слово из программы}
  Var Temp_str:string;
  Begin
    Temp_str:=''; {Составляемая строка}
    flag1:=false;  {Проверка на строку}
    while AnaStr[PositionRead] in Symbol do {Пропускать управляющие символы}
      Begin
        if AnaStr[PositionRead]='"' then Begin inc(PositionRead); flag1:=not(flag1); Break; End;
        inc(PositionRead);
      End;
    while (not(AnaStr[PositionRead] in Symbol)) or flag1 do
      Begin
        Temp_str:=Temp_str+AnaStr[PositionRead];
        inc(PositionRead);
        if AnaStr[PositionRead]='"' then flag1:=not(flag1);
      End;
    CutWord:=Temp_str; {Возвращает вырезанное слово}
  End;

Procedure Error(code:word; StrTmp,AnalizeStr:string);
  Begin
    TextColor(12);
    Writeln('При компиляции возникла ошибка с кодом ',code,' .');
    Writeln(StrTmp);
    TextColor(11);
    if length(AnalizeStr)>=1 then Writeln('В строке - ',AnalizeStr);
    Halt(code);
  End;

Procedure WriteInFile1(Byte1:word);
  Begin
    Code[PositionCode]:=Byte1;
    inc(PositionCode);
  End;

Procedure WriteInFile2(Byte1,Byte2:word);
  Begin
    Code[PositionCode]:=Byte1;
    Code[PositionCode+1]:=Byte2;
    inc(PositionCode,2);
  End;

Procedure WriteInFile3(Byte1,Byte2,Byte3:word);
  Begin
    Code[PositionCode]:=Byte1;
    Code[PositionCode+1]:=Byte2;
    Code[PositionCode+2]:=Byte3;
    inc(PositionCode,3);
  End;

Procedure WriteInFile4(Byte1,Byte2,Byte3,Byte4:word);
  Begin
    Code[PositionCode]:=Byte1;
    Code[PositionCode+1]:=Byte2;
    Code[PositionCode+2]:=Byte3;
    Code[PositionCode+3]:=Byte4;
    inc(PositionCode,4);
  End;

Function IfTerminal(stroka:string):word; {Проверка зарезервированных терминалов}
  Var Temp,i:word;
  Begin
    Temp:=0;
    for i:=1 to MAX_WORD_ANALIZE do
      if Word_Analize[i]=stroka then Begin Temp:=i; Break; End;
    IfTerminal:=Temp;
  End;

Function IfVar(stroka:string):word; {Проверка переменной}
  Var Temp,i:word;
  Begin
    Temp:=0;
    for i:=1 to MAX_VARIABLE do
      if VarMemory[i].NameVar=stroka then Begin Temp:=i; Break; End;
    IfVar:=Temp;
  End;

Function IfType(stroka:string):word; {Проверка типа переменной}
  Var Temp,i:word;
  Begin
    Temp:=0;
    for i:=1 to 4 do
      if TypesVar[i].NameType=stroka then Begin Temp:=i; Break; End;
    IfType:=Temp;
  End;

Function CutString(sdf:string; Pos:Word):string; {Вырезание строки с ошибкой}
  Var Temp:string;
  Begin
    Temp:=sdf;
    while not(AnaStr[Pos] in [#10,#13]) do Begin Temp:=Temp+AnaStr[Pos]; inc(Pos); End;
    CutString:=Temp;
  End;

{Function IfChar(num:byte):char; {Увеличивает указатель до следующего символа и возращает символ}
{  Begin
    { num=1 Сканирует до следуещего символа
      num=2 Сканирует до следуещего не символа
    }
{    if num=1 then while not(AnaStr[PositionRead] in Symbol) do inc(PositionRead);
    if num=2 then while AnaStr[PositionRead] in Symbol do inc(PositionRead);
    IfChar:=AnaStr[PositionRead];
  End;
}

Procedure WriteStringCode(CutWord:string); {Печать строки}
  Var Point:word;
  Begin
    CutWord:=CutWord+'$';
    Point:=PositionData+Shift;
    for i:=1 to length(CutWord) do Begin Data[PositionData]:=ord(CutWord[i]); inc(PositionData); End;
    WriteInFile3($BA,Lo(Point),Hi(point));
    WriteInFile2($B4,$09);
    WriteInFile2($CD,$21);
  End;

Procedure WriteNewLineCode; {Перевод курсора на новую строку}
  Begin
    if Linenews=0 then
      Begin
        Linenews:=PositionData+Shift;
        Data[PositionData]:=13; Data[PositionData+1]:=10; Data[PositionData+2]:=ord('$');
        inc(PositionData,3);
      End;
    WriteInFile3($BA,Lo(Linenews),Hi(Linenews));
    WriteInFile2($B4,$09);
    WriteInFile2($CD,$21);
  End;

Procedure WriteChar; {Печать символа}
  Begin
    if Charnews=0 then
      Begin
        Charnews:=PositionData+Shift;
        Data[PositionData]:=32; Data[PositionData+1]:=ord('$');
        inc(PositionData,2);
      End;
    WriteInFile3($BA,Lo(Charnews),Hi(Charnews));
    WriteInFile2($8B,$FA);
    WriteInFile2($88,$05);
    WriteInFile2($B4,$09);
    WriteInFile2($CD,$21);
  End;

Procedure WriteNumberCode(Syst,Znak:word); {Процедура печати содержимого AX}
  Begin
    if WrtNum=0 then
      Begin
        WrtNum:=PositionData+1;{Shift;}
        Data[PositionData+00]:=$51;
        Data[PositionData+01]:=$B2; Data[PositionData+02]:=$24;
        Data[PositionData+03]:=$88; Data[PositionData+04]:=$15;
        Data[PositionData+05]:=$47;
        Data[PositionData+06]:=$E2; Data[PositionData+07]:=$FB;
        Data[PositionData+08]:=$59;
        Data[PositionData+09]:=$33; Data[PositionData+10]:=$D2;
        Data[PositionData+11]:=$4F;
        Data[PositionData+12]:=$F7; Data[PositionData+13]:=$F3;
        Data[PositionData+14]:=$80; Data[PositionData+15]:=$FA; Data[PositionData+16]:=$0A;
        Data[PositionData+17]:=$73; Data[PositionData+18]:=$07;
        Data[PositionData+19]:=$80; Data[PositionData+20]:=$C2; Data[PositionData+21]:=$30;
        Data[PositionData+22]:=$88; Data[PositionData+23]:=$15;
        Data[PositionData+24]:=$EB; Data[PositionData+25]:=$05;
        Data[PositionData+26]:=$80; Data[PositionData+27]:=$C2; Data[PositionData+28]:=$37;
        Data[PositionData+29]:=$88; Data[PositionData+30]:=$15;
        Data[PositionData+31]:=$33; Data[PositionData+32]:=$D2;
        Data[PositionData+33]:=$4F;
        Data[PositionData+34]:=$E2; Data[PositionData+35]:=$E8;
        Data[PositionData+36]:=$47;
        Data[PositionData+37]:=$8A; Data[PositionData+38]:=$55; Data[PositionData+39]:=$01;
        Data[PositionData+40]:=$80; Data[PositionData+41]:=$FA; Data[PositionData+42]:=$24;
        Data[PositionData+43]:=$74; Data[PositionData+44]:=$0A;
        Data[PositionData+45]:=$8A; Data[PositionData+46]:=$15;
        Data[PositionData+47]:=$80; Data[PositionData+48]:=$FA; Data[PositionData+49]:=$30;
        Data[PositionData+50]:=$75; Data[PositionData+51]:=$03;
        Data[PositionData+52]:=$47;
        Data[PositionData+53]:=$EB; Data[PositionData+54]:=$EE;
        Data[PositionData+55]:=$8B; Data[PositionData+56]:=$D7;
        Data[PositionData+57]:=$B4; Data[PositionData+58]:=$09;
        Data[PositionData+59]:=$CD; Data[PositionData+60]:=$21;
        Data[PositionData+61]:=$C3;
        inc(PositionData,62);

        BuffNum:=PositionData+Shift;
        for i:=1 to 17 do Begin Data[PositionData]:=ord('$'); inc(PositionData); End;
      End;
    if Syst=0 then WriteInFile3($BB,Lo(10),Hi(10)); {Система счисления}
    WriteInFile3($BF,Lo(BuffNum),Hi(BuffNum)); {адресс буфера}
    WriteInFile3($B9,Lo(Znak),Hi(Znak)); {0004 количество знаков}
    WriteInFile3($E8,$00,$00); {Переход на печать}

    PointVar[PositionVarPoint].Position:=PositionCode-2; {Позиция подстановки}
    PointVar[PositionVarPoint].Length:=0;
    PointVar[PositionVarPoint].PosPerexod:=WrtNum; {Позиция перехода}
    inc(PositionVarPoint);
  End;

Procedure ReadCode(Syst:word; symb:boolean);
  Begin
    if (ReadNum=0) and not(symb) then
      Begin
        ReadNum:=PositionData+1;{Shift;}
        Data[PositionData+00]:=$33; Data[PositionData+01]:=$C0;
        Data[PositionData+02]:=$8A; Data[PositionData+03]:=$15;
        Data[PositionData+04]:=$80; Data[PositionData+05]:=$FA; Data[PositionData+06]:=$20;
        Data[PositionData+07]:=$72; Data[PositionData+08]:=$18;
        Data[PositionData+09]:=$80; Data[PositionData+10]:=$FA; Data[PositionData+11]:=$20;
        Data[PositionData+12]:=$74; Data[PositionData+13]:=$10;
        Data[PositionData+14]:=$80; Data[PositionData+15]:=$EA; Data[PositionData+16]:=$30;
        Data[PositionData+17]:=$80; Data[PositionData+18]:=$FA; Data[PositionData+19]:=$09;
        Data[PositionData+20]:=$77; Data[PositionData+21]:=$08;
        Data[PositionData+22]:=$32; Data[PositionData+23]:=$F6;
        Data[PositionData+24]:=$8B; Data[PositionData+25]:=$CA;
        Data[PositionData+26]:=$F7; Data[PositionData+27]:=$E3;
        Data[PositionData+28]:=$03; Data[PositionData+29]:=$C1;
        Data[PositionData+30]:=$47;
        Data[PositionData+31]:=$EB; Data[PositionData+32]:=$E1;
        Data[PositionData+33]:=$C3;
        inc(PositionData,34);
      End;
    if BuffRead=0 then
      Begin
        BuffRead:=PositionData+Shift;
        Data[PositionData]:=10; inc(PositionData);
        for i:=1 to 10 do Begin Data[PositionData]:=0; inc(PositionData); End;
      End;
    WriteInFile1($53);  {push  BX}
    WriteInFile3($BF,Lo(BuffRead),Hi(BuffRead)); {mov   DI,offset fdf}
    if symb then
      WriteInFile2($B4,$02) {mov   AH,2}
     Else
      WriteInFile2($B4,$06); {mov   AH,7}
    WriteInFile2($88,$25); {mov   [DI],AH}
    WriteInFile2($8B,$D7); {mov   DX,DI}
    WriteInFile2($B4,$0A); {mov   AH,0Ah}
    WriteInFile2($CD,$21); {int   21h}
    WriteInFile3($83,$C7,$02); {add   DI,2}
    if not(symb) then
      Begin
        WriteInFile3($BB,Lo(Syst),Hi(Syst)); {mov  BX,10}
        WriteInFile3($E8,$00,$00); {call  Char_to_int}

        PointVar[PositionVarPoint].Position:=PositionCode-2; {Позиция подстановки}
        PointVar[PositionVarPoint].Length:=0;
        PointVar[PositionVarPoint].PosPerexod:=ReadNum; {Позиция перехода}
        inc(PositionVarPoint);
      End
     Else
      Begin
        WriteInFile2($8A,$05); {mov   AL,[DI]}
      End;
    WriteInFile1($5B); {pop   BX}
    if symb then
      WriteInFile2($88,$07)  {mov   [BX],AL}
     Else
      WriteInFile2($89,$07); {mov   [BX],AX}
  End;

Procedure GotoXYCode;
  Begin
    if (GotoPos=0) then
      Begin
        GotoPos:=PositionData+1;{Shift;}
        Data[PositionData+00]:=$8A; Data[PositionData+01]:=$D3; {mov DL,BL}
        Data[PositionData+02]:=$33; Data[PositionData+03]:=$DB; {xor BX,BX}
        Data[PositionData+04]:=$8A; Data[PositionData+05]:=$F0; {mov DH,AL}
        Data[PositionData+06]:=$B4; Data[PositionData+07]:=$02; {mov AH,02h}
        Data[PositionData+08]:=$CD; Data[PositionData+09]:=$10; {int 10h}
        Data[PositionData+10]:=$C3;
        inc(PositionData,12);
      End;
    WriteInFile3($E8,$00,$00); {call gotoxy; }

    PointVar[PositionVarPoint].Position:=PositionCode-2; {Позиция подстановки}
    PointVar[PositionVarPoint].Length:=0;
    PointVar[PositionVarPoint].PosPerexod:=GotoPos; {Позиция перехода}
    inc(PositionVarPoint);
  End;

Procedure ClrscrCode;
  Begin
    if (ClrPos=0) then
      Begin
        ClrPos:=PositionData+1;{Shift;}
        Data[PositionData+00]:=$B7; Data[PositionData+01]:=$0F; {mov BH,15}
        Data[PositionData+02]:=$B3; Data[PositionData+03]:=$20; {mov BL,32}
        Data[PositionData+04]:=$33; Data[PositionData+05]:=$F6; {xor SI,SI}
        Data[PositionData+06]:=$B8; Data[PositionData+07]:=$00; Data[PositionData+08]:=$B8; {mov AX,0B800h}
        Data[PositionData+09]:=$8E; Data[PositionData+10]:=$C0; {mov ES,AX}
        Data[PositionData+11]:=$B9; Data[PositionData+12]:=$D0; Data[PositionData+13]:=$07; {mov CX,80*25}
        Data[PositionData+14]:=$26; Data[PositionData+15]:=$89; Data[PositionData+16]:=$1C; {mov ES:[SI],BX}
        Data[PositionData+17]:=$46; {inc SI}
        Data[PositionData+18]:=$46; {inc SI}
        Data[PositionData+19]:=$E2; Data[PositionData+20]:=$F9; {loop llll}
        Data[PositionData+21]:=$C3; {ret}
        inc(PositionData,22);
      End;
    WriteInFile3($E8,$00,$00); {call gotoxy; }

    PointVar[PositionVarPoint].Position:=PositionCode-2; {Позиция подстановки}
    PointVar[PositionVarPoint].Length:=0;
    PointVar[PositionVarPoint].PosPerexod:=ClrPos; {Позиция перехода}
    inc(PositionVarPoint);
  End;

Procedure CompilerProgr;
  Var StrTemp:string;
      pt,Perevod,Code,i,PosStr,ForVar:word;
      PVT1,PVT2,PVT3,PVT4,PVT5,PVT6:word;
      BeginEnd,Flag:boolean;
      symb,znak1,znak2:char;
  Begin
    if StartProg then BeginEnd:=True Else BeginEnd:=False;
    Flag:=true;
    while Flag do
      Begin
        IdentTemp:=CutWord;
        PosStr:=PositionRead;
        case IfTerminal(IdentTemp) of
          01: Begin {While}
                If StartProg and (BeginTemp>0) then
                  Begin
                    PointVar[PositionVarPoint].PosPerexod:=PositionCode-2; {Позиция перехода}
                    PointVar[PositionVarPoint].Length:=1;
                    PVT1:=PositionVarPoint; inc(PositionVarPoint);
                    if AnaStr[PositionRead]<>'(' then Error(1,'Нет открывающей скобки',CutString(IdentTemp,PosStr));
                    inc(PositionRead);
                    ProcE;
                    znak1:=AnaStr[PositionRead];
                    znak2:=AnaStr[PositionRead+1];
                    if not (znak1 in ['<','>','=']) then Error(1,'Ошибка в условии',CutString(IdentTemp,PosStr));
                    WriteInFile1($50); {Push AX}
                    inc(PositionRead);
                    if znak2 in ['"','>','<','='] then inc(PositionRead);
                    ProcE;
                    if AnaStr[PositionRead]<>')' then Error(1,'Нет закрывающей скобки',CutString(IdentTemp,PosStr));
                    WriteInFile1($5B); {Pop BX}
                    WriteInFile2($3B,$D8); {cmp AX,BX}
                    if (znak1='<') then WriteInFile2($72,$03); {jb ssdf ;<}
                    if (znak1='>') then WriteInFile2($77,$03); {ja ssdf ;>}
                    if (znak1='<') and (znak2='=') then WriteInFile2($76,$03); {jbe ssdf ;<=}
                    if (znak1='>') and (znak2='=') then WriteInFile2($73,$03); {jae ssdf ;>=}
                    if (znak1='=') and (znak2='=') then WriteInFile2($74,$03); {je ssdf ;=}
                    if (znak1='<') and (znak2='>') then WriteInFile2($75,$0D); {jne ssdf ;<>}
                    WriteInFile3($E9,$00,$00); {jmp addr }
                    PointVar[PositionVarPoint].Position:=PositionCode-2; {Позиция подстановки}
                    PVT2:=PositionVarPoint; inc(PositionVarPoint);
                    StrTemp:=CutWord;
                    if StrTemp='DO' then
                      Begin
                        pt:=PositionRead; StrTemp:=CutWord;
                        if StrTemp='BEGIN' then
                          Begin
                            PositionRead:=pt;
                            CompilerProgr;
                          End
                         Else
                          Error(1,'Блок не выделен',CutString(IdentTemp,PosStr));
                      End
                     Else
                      Error(1,'Отсутствует оператор DO',CutString(IdentTemp,PosStr));

                    WriteInFile3($E9,$00,$00); {jmp addr }
                    PointVar[PVT1].Position:=PositionCode-2; {Позиция подстановки}

                    PointVar[PVT2].PosPerexod:=PositionCode-2; {Позиция перехода}
                    PointVar[PVT2].Length:=1;

                  End
                 Else
                  Error(1,'Неправильное место определения оператора',CutString(IdentTemp,PosStr));
              End;
          02: Begin {For}
                If StartProg and (BeginTemp>0) then
                  Begin
                    StrTemp:=CutWord;
                    pt:=IfVar(StrTemp);
                    if VarMemory[pt].TypeVar<>'WORD' then
                      Error(1,'Переменная должна быть типа Word',CutString(IdentTemp,PosStr));
                    if pt<>0 then
                      Begin
                        if (AnaStr[PositionRead]='=') then
                          Begin
                            PositionRead:=PositionRead-length(StrTemp);
                            ProcE;
{                            StrTemp:=CutWord;}
                            symb:=AnaStr[PositionRead];
                            if (symb='<') or (symb='>') then
                              Begin
                                WriteInFile1($53); {Push BX}
                                StrTemp:=CutWord;
                                PositionRead:=PositionRead-length(StrTemp);
                                ProcE;
                                WriteInFile1($5B); {pop     BX}
                                ForVar:=PositionData+Shift;
                                Data[PositionData]:=0; Data[PositionData+1]:=0;
                                inc(PositionData,2);
                                WriteInFile3($BF,Lo(ForVar),Hi(ForVar)); {mov DI,addr}
                                WriteInFile2($89,$05); {mov [DI],AX}

                                PointVar[PositionVarPoint].PosPerexod:=PositionCode-2; {Позиция перехода}
                                PointVar[PositionVarPoint].Length:=1;
                                PVT1:=PositionVarPoint;
                                inc(PositionVarPoint);
                                WriteInFile1($53); {Push BX}
                                WriteInFile3($BF,Lo(ForVar),Hi(ForVar)); {mov DI,addr}
                                WriteInFile2($8B,$05); {mov AX,[DI]}
                                WriteInFile2($39,$07); {cmp [BX],AX}
                                if (symb='>') then WriteInFile2($76,$03); {jbe +3}
                                if (symb='<') then WriteInFile2($73,$03); {jae ssdf}
                                WriteInFile3($E9,$00,$00); {jmp addr }
                                PointVar[PositionVarPoint].Position:=PositionCode-2; {Позиция подстановки}
                                PVT2:=PositionVarPoint;
                                inc(PositionVarPoint);
                                StrTemp:=CutWord;
                                if StrTemp='DO' then
                                  Begin
                                    pt:=PositionRead; StrTemp:=CutWord;
                                    if StrTemp='BEGIN' then
                                      Begin
                                        PositionRead:=pt;
                                        CompilerProgr;
                                      End
                                     Else
                                      Error(1,'Блок не выделен',CutString(IdentTemp,PosStr));
                                  End
                                 Else
                                  Error(1,'Цикл записан неверно',CutString(IdentTemp,PosStr));
                                WriteInFile1($5B); {pop     BX}
                                if (symb='>') then WriteInFile2($FF,$07); {inc word ptr [BX]}
                                if (symb='<') then WriteInFile2($FF,$0F); {dec word ptr [BX]}
                                WriteInFile3($E9,$00,$00); {jmp addr }
                                PointVar[PVT1].Position:=PositionCode-2; {Позиция подстановки}
                                PointVar[PVT2].PosPerexod:=PositionCode-2; {Позиция перехода}
                                PointVar[PVT2].Length:=1;
                              End
                             Else
                              Error(1,'Цикл записан неверно',CutString(IdentTemp,PosStr));
                          End
                         Else
                          Error(1,'Нет знака равенства',CutString(IdentTemp,PosStr));
                      End
                     Else
                      Error(1,'Переменная не определена',CutString(IdentTemp,PosStr));
                  End
                 Else
                  Error(1,'Неправильное место определения оператора',CutString(IdentTemp,PosStr));
              End;
          03: Begin {If}
                If StartProg and (BeginTemp>0) then
                  Begin
                    if AnaStr[PositionRead]<>'(' then Error(1,'Нет открывающей скобки',CutString(IdentTemp,PosStr));
                    inc(PositionRead);
                    ProcE;
                    znak1:=AnaStr[PositionRead];
                    znak2:=AnaStr[PositionRead+1];
                    if not (znak1 in ['<','>','=']) then Error(1,'Ошибка в условии',CutString(IdentTemp,PosStr));
                    WriteInFile1($50); {Push AX}
                    inc(PositionRead);
                    if znak2 in ['"','>','<','='] then inc(PositionRead);
{                    StrTemp:=CutWord;
                    PositionRead:=PositionRead-length(StrTemp);}
                    ProcE;
                    if AnaStr[PositionRead]<>')' then Error(1,'Нет закрывающей скобки',CutString(IdentTemp,PosStr));
                    WriteInFile1($5B); {Pop BX}
                    WriteInFile2($3B,$D8); {cmp AX,BX}
                    if (znak1='<') then WriteInFile2($72,$03); {jb ssdf ;<}
                    if (znak1='>') then WriteInFile2($77,$03); {ja ssdf ;>}
                    if (znak1='<') and (znak2='=') then WriteInFile2($76,$03); {jbe ssdf ;<=}
                    if (znak1='>') and (znak2='=') then WriteInFile2($73,$03); {jae ssdf ;>=}
                    if (znak1='=') and (znak2='=') then WriteInFile2($74,$03); {je ssdf ;=}
                    if (znak1='<') and (znak2='>') then WriteInFile2($75,$0D); {jne ssdf ;<>}
                    WriteInFile3($E9,$00,$00); {jmp addr }
                    PointVar[PositionVarPoint].Position:=PositionCode-2; {Позиция подстановки}
                    PVT1:=PositionVarPoint; inc(PositionVarPoint);
                    StrTemp:=CutWord;
                    if StrTemp='THEN' then
                      Begin
                        pt:=PositionRead; StrTemp:=CutWord;
                        if StrTemp='BEGIN' then
                          Begin
                            PositionRead:=pt;
                            CompilerProgr;
                          End
                         Else
                          Error(1,'Блок не выделен',CutString(IdentTemp,PosStr));
                      End
                     Else
                      Error(1,'Отсутствует оператор THEN',CutString(IdentTemp,PosStr));

                    WriteInFile3($E9,$00,$00); {jmp addr }
                    PointVar[PositionVarPoint].Position:=PositionCode-2; {Позиция подстановки}
                    PVT2:=PositionVarPoint; inc(PositionVarPoint);

                    PointVar[PVT1].PosPerexod:=PositionCode-2; {Позиция перехода}
                    PointVar[PVT1].Length:=1;
                    pt:=PositionRead;
                    StrTemp:=CutWord;
                    if StrTemp='ELSE' then
                      Begin
                        pt:=PositionRead; StrTemp:=CutWord;
                        if StrTemp='BEGIN' then
                          Begin
                            PositionRead:=pt;
                            CompilerProgr;
                          End
                         Else
                          Error(1,'Блок не выделен',CutString(IdentTemp,PosStr));
                      End
                     Else PositionRead:=pt;

                    PointVar[PVT2].PosPerexod:=PositionCode-2; {Позиция перехода}
                    PointVar[PVT2].Length:=1;
                   End
                 Else
                  Error(1,'Неправильное место определения оператора',CutString(IdentTemp,PosStr));
              End;
          04: Begin {Begin}
                if (BeginTemp>0) and not(StartProg) then
                  Error(1,'Структура "BEGIN" и "END." должна определяться один раз','');
                StartProg:=True; inc(BeginOpred); inc(BeginTemp);
                CompilerProgr;
                flag:=false;
              End;
          05: Begin {End}
                if not(StartProg) or not(BeginEnd) then Error(1,'Небыло найдено слово BEGIN','');
                dec(BeginOpred);
                if (AnaStr[PositionRead]='.') then
                  Begin
                    if BeginOpred=0 then StartProg:=False else Error(1,'Несовпадение BEGIN~ов и END~ов','');
                    WriteInFile3($B8,$00,$4C); {Запись команды mov ax,4C00}
                    WriteInFile2($CD,$21);     {Запись команды int 21}
                  End;
{                if BeginOpred=0 then
                  Begin
                    if BeginOpred=0 then StartProg:=False else Error(1,'Несовпадение BEGIN~ов и END~ов','');}
{                    WriteInFile3($B8,$00,$4C); {Запись команды mov ax,4C00}
{                    WriteInFile2($CD,$21);     {Запись команды int 21}
{                  End;}
                BeginEnd:=False;
                flag:=false;
              End;
          06: Begin {Write}
                If StartProg and (BeginTemp>0) then
                  Begin
                    if AnaStr[PositionRead]<>'(' then
                      Error(1,'Ошибка в написании оператора "Write"',CutString(IdentTemp,PosStr));
                    if AnaStr[PositionRead+1]='"' then {Если строка}
                      Begin
                        if AnaStr[PositionRead+2]<>'"' then
                          WriteStringCode(CutWord)
                         Else
                          Begin WriteStringCode(''); inc(PositionRead,2); End;
                        if AnaStr[PositionRead]<>'"' then
                          Error(1,'Ошибка в растановке кавычек',CutString(IdentTemp,PosStr));
                        If AnaStr[PositionRead+2]<>';' then
                          Error(1,'Не найдена ";"',CutString(IdentTemp,PosStr));
                        inc(PositionRead,2);
                      End
                     else
                      Begin
                        {if AnaStr[PositionRead+1] in Digits then {Если число}
                         { Begin
{                            StrTemp:=CutWord;}
                         Code:=PositionRead;
                         StrTemp:=CutWord;
                         pt:=IfVar(StrTemp);
                         PositionRead:=Code;
                         inc(PositionRead);
                         ProcE;
                         If (AnaStr[PositionRead]='|') or (AnaStr[PositionRead]=':') then
                           Begin
                             Inc(PositionRead);
                             WriteInFile1($50); {Push AX}
                             ProcE;
                             WriteInFile1($5B); {Pop BX}
                             WriteInFile1($93); {Xchg AX,BX}
                             WriteNumberCode(1,16);
                             While AnaStr[PositionRead]=')' do inc(PositionRead);
                           End
                          Else
                           Begin
                             if VarMemory[pt].TypeVar<>'CHAR' then WriteNumberCode(0,16) Else WriteChar;
                             While AnaStr[PositionRead]=')' do inc(PositionRead);
                           End;
                          If AnaStr[PositionRead]<>';' then
                            Error(1,'Не найдена ";"',CutString(IdentTemp,PosStr));
                        {  End
                         else
                          Begin
                            StrTemp:=CutWord;  {Если переменная}
                         {   If AnaStr[PositionRead]<>')' then
                              Error(1,'Ошибка в написании оператора "Write"',CutString(IdentTemp,PosStr));
                            If AnaStr[PositionRead+1]<>';' then
                              Error(1,'Не найдена ";"',CutString(IdentTemp,PosStr));
                            pt:=IfVar(StrTemp);
                            if pt<>0 then
                              Begin
                                if VarMemory[pt].TypeVar='CHAR' then Begin End;
                                if VarMemory[pt].TypeVar='INTEGER' then Begin End;
                                if VarMemory[pt].TypeVar='BYTE' then Begin End;
                                if VarMemory[pt].TypeVar='WORD' then Begin End;
                              End
                             Else
                              Error(1,'Переменная не была определена',CutString(IdentTemp,PosStr));
                          End;}
                      End;
                  End
                 Else
                  Error(1,'Неправильное место определения оператора',CutString(IdentTemp,PosStr));
              End;
          07: Begin {Read}
                If StartProg and (BeginTemp>0) then
                  Begin
                    StrTemp:=CutWord;
                    pt:=IfVar(StrTemp);
                    if pt<>0 then
                      Begin
                        PositionRead:=PositionRead-Length(StrTemp);
                        ProcE;
                         if AnaStr[PositionRead]<>')' then
                          Error(1,'Неправильная запись оператора Read',CutString(IdentTemp,PosStr));
                        if AnaStr[PositionRead+1]<>';' then
                          Error(1,'Нет ";"',CutString(IdentTemp,PosStr));
                        if VarMemory[pt].TypeVar='CHAR' then ReadCode(10,True) Else ReadCode(10,False);
                      End
                     Else
                      Error(1,'Переменная не определена',CutString(IdentTemp,PosStr));
                  End
                 Else
                  Error(1,'Неправильное место определения оператора',CutString(IdentTemp,PosStr));
              End;
          08: Begin {Define}
                If not(StartProg) and (BeginTemp=0) then
                  Begin
                    StrTemp:=CutWord;
                    if IfVar(StrTemp)=0 then
                      Begin
                        if AnaStr[PositionRead]<>':' then
                          Error(1,'Неправильное определение переменной',CutString(IdentTemp,PosStr));
                        pt:=IfType(CutWord);
                        if pt<>0 then
                          Begin
                            if AnaStr[PositionRead]='[' then
                              Begin
                                Val(CutWord,Perevod,Code);
                                If Code<>0 Then
                                  Error(1,'Неправильное определение массива',CutString(IdentTemp,PosStr));
                                If AnaStr[PositionRead]<>']' then
                                  Error(1,'Неправильная запись массива',CutString(IdentTemp,PosStr));
                                If AnaStr[PositionRead+1]<>';' then
                                  Error(1,'Не найдена ";"',CutString(IdentTemp,PosStr));
                                VarMemory[NewVarPoint].SizeVar:=TypesVar[pt].SizeType*Perevod;
                              End
                             Else
                              Begin
                                If AnaStr[PositionRead]<>';' then
                                  Error(1,'Не найдена ";"',CutString(IdentTemp,PosStr));
                                VarMemory[NewVarPoint].SizeVar:=TypesVar[pt].SizeType;
                              End;
                            VarMemory[NewVarPoint].NameVar:=StrTemp;
                            VarMemory[NewVarPoint].PointVar:=PositionData;
                            VarMemory[NewVarPoint].TypeVar:=TypesVar[pt].NameType;
                            VarMemory[NewVarPoint].Arifmetic:=TypesVar[pt].ArifType;
                            VarMemory[NewVarPoint].SizeType:=TypesVar[pt].SizeType;
                            PositionData:=PositionData+VarMemory[NewVarPoint].SizeVar;
                            inc(NewVarPoint);
                          End
                         Else
                          Error(1,'Несоответствие типа переменной',CutString(IdentTemp,PosStr));
                      End
                     Else
                      Error(1,'Повторное переопределение переменной',CutString(IdentTemp,PosStr));
                  End
                 Else
                  Error(1,'Неправильное место определения переменной',CutString(IdentTemp,PosStr));
              End;
          09: Begin {Shl}
                If StartProg and (BeginTemp>0) then
                  Begin
                    StrTemp:=CutWord;
                    pt:=IfVar(StrTemp);
                    if pt<>0 then
                      Begin
                        ProcE;
                        WriteInFile1($53); {Push BX}
                        if (AnaStr[PositionRead]<>'<') or (AnaStr[PositionRead+1]<>'<') then
                          Error(1,'Сдвиг записан неверно',CutString(IdentTemp,PosStr));
                        inc(PositionRead,2);
                        if (AnaStr[PositionRead]=')') then
                          Error(1,'Сдвиг записан неверно',CutString(IdentTemp,PosStr));
                        ProcE;
                        WriteInFile2($8A,$C8); {mov CL,AL}
                        WriteInFile1($5B); {Pop BX}
                        if VarMemory[pt].SizeType=2 then
                          Begin
                            WriteInFile2($8B,$07); {mov AX,[BX]}
                            WriteInFile2($D3,$E0); {shl AX,CL}
                            WriteInFile2($89,$07); {mov [BX],AX}
                          End
                         Else
                          Begin
                            WriteInFile2($8A,$07); {mov AL,[BX]}
                            WriteInFile2($D2,$E0); {shl AL,CL}
                            WriteInFile2($88,$07); {mov [BX],AL}
                          End;
                      End
                     Else
                      Error(1,'Ошибка в сдвиге переменной',CutString(IdentTemp,PosStr));
                    If AnaStr[PositionRead+1]<>';' then
                      Error(1,'Не найдена ";"',CutString(IdentTemp,PosStr));
                  End
                 Else
                  Error(1,'Неправильное место определения переменной',CutString(IdentTemp,PosStr));
              End;
          10: Begin {Shr}
                If StartProg and (BeginTemp>0) then
                  Begin
                    StrTemp:=CutWord;
                    pt:=IfVar(StrTemp);
                    if pt<>0 then
                      Begin
                        ProcE;
                        WriteInFile1($53); {Push BX}
                        if (AnaStr[PositionRead]<>'>') or (AnaStr[PositionRead+1]<>'>') then
                          Error(1,'Сдвиг записан неверно',CutString(IdentTemp,PosStr));
                        inc(PositionRead,2);
                        if (AnaStr[PositionRead]=')') then
                          Error(1,'Сдвиг записан неверно',CutString(IdentTemp,PosStr));
                        ProcE;
                        WriteInFile2($8A,$C8); {mov CL,AL}
                        WriteInFile1($5B); {Pop BX}
                        if VarMemory[pt].SizeType=2 then
                          Begin
                            WriteInFile2($8B,$07); {mov AX,[BX]}
                            WriteInFile2($D3,$E8); {shr AX,CL}
                            WriteInFile2($89,$07); {mov [BX],AX}
                          End
                         Else
                          Begin
                            WriteInFile2($8A,$07); {mov AL,[BX]}
                            WriteInFile2($D2,$E8); {shr AL,CL}
                            WriteInFile2($88,$07); {mov [BX],AL}
                          End;
                      End
                     Else
                      Error(1,'Ошибка в сдвиге переменной',CutString(IdentTemp,PosStr));
                    If AnaStr[PositionRead+1]<>';' then
                      Error(1,'Не найдена ";"',CutString(IdentTemp,PosStr));
                  End
                 Else
                  Error(1,'Неправильное место определения переменной',CutString(IdentTemp,PosStr));
              End;
          11: Begin {Xor}
                If StartProg and (BeginTemp>0) then
                  Begin
                    StrTemp:=CutWord;
                    pt:=IfVar(StrTemp);
                    if pt<>0 then
                      Begin
                        ProcE;
                        WriteInFile1($53); {Push BX}
                        if (AnaStr[PositionRead]<>'!') then
                          Error(1,'Xor записан неверно',CutString(IdentTemp,PosStr));
                        inc(PositionRead);
                        if (AnaStr[PositionRead]=')') then
                          Error(1,'Xor записан неверно',CutString(IdentTemp,PosStr));
                        ProcE;
                        WriteInFile1($5B); {Pop BX}
                        if VarMemory[pt].SizeType=2 then
                            WriteInFile2($31,$07) {xor [BX],AX}
                         Else
                            WriteInFile2($30,$07); {xor [BX],AL}
                      End
                     Else
                      Error(1,'Ошибка в переменной',CutString(IdentTemp,PosStr));
                    If AnaStr[PositionRead+1]<>';' then
                      Error(1,'Не найдена ";"',CutString(IdentTemp,PosStr));
                  End
                 Else
                  Error(1,'Неправильное место определения переменной',CutString(IdentTemp,PosStr));
              End;
          12: Begin {Or}
                If StartProg and (BeginTemp>0) then
                  Begin
                    StrTemp:=CutWord;
                    pt:=IfVar(StrTemp);
                    if pt<>0 then
                      Begin
                        ProcE;
                        WriteInFile1($53); {Push BX}
                        if (AnaStr[PositionRead]<>'!') then
                          Error(1,'Or записан неверно',CutString(IdentTemp,PosStr));
                        inc(PositionRead);
                        if (AnaStr[PositionRead]=')') then
                          Error(1,'Or записан неверно',CutString(IdentTemp,PosStr));
                        ProcE;
                        WriteInFile1($5B); {Pop BX}
                        if VarMemory[pt].SizeType=2 then
                            WriteInFile2($09,$07) {or [BX],AX}
                         Else
                            WriteInFile2($08,$07); {or [BX],AL}
                      End
                     Else
                      Error(1,'Ошибка в переменной',CutString(IdentTemp,PosStr));
                    If AnaStr[PositionRead+1]<>';' then
                      Error(1,'Не найдена ";"',CutString(IdentTemp,PosStr));
                  End
                 Else
                  Error(1,'Неправильное место определения переменной',CutString(IdentTemp,PosStr));
              End;
          13: Begin {And}
                If StartProg and (BeginTemp>0) then
                  Begin
                    StrTemp:=CutWord;
                    pt:=IfVar(StrTemp);
                    if pt<>0 then
                      Begin
                        ProcE;
                        WriteInFile1($53); {Push BX}
                        if (AnaStr[PositionRead]<>'!') then
                          Error(1,'And записан неверно',CutString(IdentTemp,PosStr));
                        inc(PositionRead);
                        if (AnaStr[PositionRead]=')') then
                          Error(1,'And записан неверно',CutString(IdentTemp,PosStr));
                        ProcE;
                        WriteInFile1($5B); {Pop BX}
                        if VarMemory[pt].SizeType=2 then
                            WriteInFile2($21,$07) {and [BX],AX}
                         Else
                            WriteInFile2($20,$07); {and [BX],AL}
                      End
                     Else
                      Error(1,'Ошибка в переменной',CutString(IdentTemp,PosStr));
                    If AnaStr[PositionRead+1]<>';' then
                      Error(1,'Не найдена ";"',CutString(IdentTemp,PosStr));
                  End
                 Else
                  Error(1,'Неправильное место определения переменной',CutString(IdentTemp,PosStr));
              End;
          14: Begin {Newline}
                If StartProg and (BeginTemp>0) then
                  Begin
                    If AnaStr[PositionRead]<>';' then
                      Error(1,'Не найдена ";"',CutString(IdentTemp,PosStr));
                    WriteNewLineCode;
                  End
                 Else
                  Error(1,'Неправильное место определения переменной',CutString(IdentTemp,PosStr));
              End;
          15: Begin {Repeat}
                If StartProg and (BeginTemp>0) then
                  Begin
                    PointVar[PositionVarPoint].PosPerexod:=PositionCode-2; {Позиция перехода}
                    PointVar[PositionVarPoint].Length:=1;
                    PVT1:=PositionVarPoint; inc(PositionVarPoint);
                    CompilerProgr;

                    pt:=PositionRead;
                    StrTemp:=CutWord;
                    if StrTemp<>'UNTIL' then
                      Begin
                        if IdentTemp<>'UNTIL' then Error(1,'Отсутствует оператор UNTIL','');
                        PositionRead:=pt;
                      End;

                    if AnaStr[PositionRead]<>'(' then Error(1,'Нет открывающей скобки',CutString(IdentTemp,PosStr));
                    inc(PositionRead);
                    ProcE;
                    znak1:=AnaStr[PositionRead];
                    znak2:=AnaStr[PositionRead+1];
                    if not (znak1 in ['<','>','=']) then Error(1,'Ошибка в условии Repeat Until',CutString(IdentTemp,PosStr));
                    WriteInFile1($50); {Push AX}
                    inc(PositionRead);
                    if znak2 in ['"','>','<','='] then inc(PositionRead);
                    ProcE;
                    if AnaStr[PositionRead]<>')' then Error(1,'Нет закрывающей скобки',CutString(IdentTemp,PosStr));
                    if AnaStr[PositionRead+1]<>';' then Error(1,'Нет ";"',CutString(IdentTemp,PosStr));
                    WriteInFile1($5B); {Pop BX}
                    WriteInFile2($3B,$D8); {cmp AX,BX}
                    if (znak1='<') then WriteInFile2($72,$03); {jb ssdf ;<}
                    if (znak1='>') then WriteInFile2($77,$03); {ja ssdf ;>}
                    if (znak1='<') and (znak2='=') then WriteInFile2($76,$03); {jbe ssdf ;<=}
                    if (znak1='>') and (znak2='=') then WriteInFile2($73,$03); {jae ssdf ;>=}
                    if (znak1='=') and (znak2='=') then WriteInFile2($74,$03); {je ssdf ;=}
                    if (znak1='<') and (znak2='>') then WriteInFile2($75,$0D); {jne ssdf ;<>}
                    WriteInFile3($E9,$00,$00); {jmp addr }
                    PointVar[PVT1].Position:=PositionCode-2; {Позиция подстановки}
                  End
                 Else
                     Error(1,'Неправильное место определения оператора',CutString(IdentTemp,PosStr));
              End;
          16: Begin {Until}
                If StartProg and (BeginTemp>0) then
                  Begin
                    flag:=false;
                  End
                 Else
                  Error(1,'Неправильное место определения переменной',CutString(IdentTemp,PosStr));
              End;
          17: Begin {Gotoxy}
                If StartProg and (BeginTemp>0) then
                  Begin
                    if AnaStr[PositionRead]<>'(' then Error(1,'Отсутствует скобка',CutString(IdentTemp,PosStr));
                    inc(PositionRead);
                    ProcE;
                    WriteInFile1($50); {push AX}
                    if AnaStr[PositionRead]<>',' then Error(1,'Отсутсвует ","',CutString(IdentTemp,PosStr));
                    inc(PositionRead);
                    ProcE;
                    if AnaStr[PositionRead]<>')' then Error(1,'Отсутствует скобка',CutString(IdentTemp,PosStr));
                    if AnaStr[PositionRead+1]<>';' then Error(1,'Отсутсвует ";"',CutString(IdentTemp,PosStr));
                    WriteInFile1($5B); {push BX}
                    GotoXYCode;
                  End
                 Else
                  Error(1,'Неправильное место определения переменной',CutString(IdentTemp,PosStr));
              End;
          18: Begin {ClrScr}
                If StartProg and (BeginTemp>0) then
                  Begin
                    if AnaStr[PositionRead]<>';' then Error(1,'Отсутсвует ";"',CutString(IdentTemp,PosStr));
                    ClrscrCode;
                    WriteInFile2($B3,$00); {mov BL,0}
                    WriteInFile2($B0,$00); {mov AL,0}
                    GotoXYCode;
                  End
                 Else
                  Error(1,'Неправильное место определения переменной',CutString(IdentTemp,PosStr));
              End;
         else
          Begin
            if AnaStr[PositionRead] in ['=','[',';'] then
              Begin
                Code:=IfVar(IdentTemp);
                if Code>0 then
                  Begin
                    PositionRead:=PosStr-Length(IdentTemp);
                    ProcE;
                    Continue;
                  End
                 Else
                  Error(1,'Переменная не была определена',CutString(IdentTemp,PosStr));
              End;
            if PositionRead>LengthFile then Exit;
            Error(1,'Ошибка в написании команды',CutString(IdentTemp,PosStr));
          End;
        end;
      End;
  End;

Procedure  ProcE;
  Var Symbol:char;
  Begin
    ProcT;
    Symbol:=' ';
    while not(AnaStr[PositionRead] in [';',' ','|',')',']','=','"','<','>','!',',',':']) do
      Begin
        WriteInFile1($50); {Push AX}
        if AnaStr[PositionRead] in ['+','-'] then Symbol:=AnaStr[PositionRead];
        inc(PositionRead); ProcT;
        WriteInFile1($5B); {Pop BX}
        WriteInFile1($93); {Xchg AX,BX}
        Case Symbol of
          '+' : Begin
                  WriteInFile2($03,$C3); {Add AX,BX}
                End;
          '-' : Begin
                  WriteInFile2($2B,$C3); {Sub AX,BX}
                End;
        End;
      End;
  End;

Procedure  ProcT;
  Var Symbol:char;
  Begin
    ProcF;
    Symbol:=' ';
    while not(AnaStr[PositionRead] in [';','+','-','|',')',']','=','"',' ','<','>','!',',',':']) do
      Begin
        WriteInFile1($50); {Push AX}
        if AnaStr[PositionRead] in ['*','/'] then Symbol:=AnaStr[PositionRead];
        inc(PositionRead); ProcF;
        WriteInFile1($5B); {Pop BX}
        WriteInFile1($93); {Xchg AX,BX}
        Case Symbol of
          '*' : Begin
                  WriteInFile2($F7,$E3); {Mul BX}
                End;
          '/' : Begin
                  WriteInFile4($33,$D2,$F7,$FB); {Idiv BX}
                End;
        End;
      End;
  End;

Procedure  ProcF;
  Var Code,dat:integer;
      tm:word;
      StrTemp:string[20];
  Begin
    if AnaStr[PositionRead] in Digits then
      Begin
        StrTemp:=CutWord;
        val(StrTemp,dat,Code);
        if Code<>0 then Error(1,'Ошибка в анализировании числа','');
        WriteInFile3($B8,Lo(dat),Hi(dat)); {mov AX,CutWord}
      End;
    if AnaStr[PositionRead] in Liters then
      Begin
        StrTemp:=CutWord;
        tm:=IfVar(StrTemp);
        if tm>0 then
          Begin
            if VarMemory[tm].SizeType=VarMemory[tm].SizeVar then
              Begin
                WriteInFile3($B8,Lo(VarMemory[tm].PointVar+shift),Hi(VarMemory[tm].PointVar+shift)); {mov AX,CutWord}
                if (AnaStr[PositionRead]<>'=') or ((AnaStr[PositionRead]='=') and (AnaStr[PositionRead+1]='=')) then
                  Begin
                    WriteInFile1($93); {Xchg AX,BX}
                    if VarMemory[tm].SizeType=2 then
                      WriteInFile2($8B,$07) {mov    AX,[BX]}
                     Else
                      Begin
                        WriteInFile2($8A,$07); {mov    AL,[BX]}
                        WriteInFile2($32,$E4); {xor    AH,AH}
                      End;
                  End;
              End
             Else
              Begin
                if AnaStr[PositionRead]<>'[' then Error(1,'Неправильная адресация переменной','');
                WriteInFile3($B8,Lo(VarMemory[tm].PointVar+shift),Hi(VarMemory[tm].PointVar+shift)); {mov AX,CutWord}
              End;
          End
         Else
          Error(1,'Переменная небыла определена','');
      End;
    Case AnaStr[PositionRead] of
      '[' : Begin
              inc(PositionRead);
              WriteInFile1($50); {Push AX}
              ProcE;
              inc(PositionRead);
              if VarMemory[tm].SizeType=2 then WriteInFile2($D1,$E0); {SHL AX,1}
              WriteInFile2($8B,$D8); {mov BX,AX}
              WriteInFile1($58);     {Pop AX}
              WriteInFile2($03,$D8);  {add BX,AX}
              WriteInFile1($93); {Xchg AX,BX}
              if (AnaStr[PositionRead]<>'=') or ((AnaStr[PositionRead]='=') and (AnaStr[PositionRead+1]='=')) then
                Begin
                  WriteInFile1($93); {Xchg AX,BX}
                  if VarMemory[tm].SizeType=2 then
                    WriteInFile2($8B,$07) {mov    AX,[BX]}
                   Else
                    Begin
                      WriteInFile2($8A,$07); {mov    AL,[BX]}
                      WriteInFile2($32,$E4); {xor    AH,AH}
                    End;
{                  inc(PositionRead);}
                End
               Else
                Begin
{                  if AnaStr[PositionRead+1] in Symbol then Error(1,'Ошибка в написании знака равенства','');}
{                  Dec(PositionRead);}
                End;
            End;
      '(' : Begin inc(PositionRead); ProcE; inc(PositionRead); End;
      '"' : Begin
              WriteInFile3($B8,Lo(ord(AnaStr[PositionRead+1])),Hi(ord(AnaStr[PositionRead+1])));
              inc(PositionRead,2);
              if AnaStr[PositionRead]<>'"' then
                Error(1,'Ошибка при считывание символа','')
               Else
                inc(PositionRead);
{              if AnaStr[PositionRead]<>';' then
                Error(1,'Нет ";"','')}
            End;
    End;
    If (AnaStr[PositionRead]='=') and (AnaStr[PositionRead+1]<>'=') Then
      Begin
        WriteInFile1($50); {Push AX}
        inc(PositionRead); ProcE;
        WriteInFile1($5B); {Pop BX}
        if VarMemory[tm].SizeType=2 then
          WriteInFile2($89,$07)  {mov    [BX],AX}
         Else
          WriteInFile2($88,$07);  {mov    [BX],AL}
      End;
  End;

Procedure FormatingComFile;
  Var Shift,Smeshen,DataTemp:word;
      Temp:integer;
      i:integer;
  Begin
    Shift:=1+PositionData;
    OutStr[0]:=$E9; OutStr[1]:=Lo(Shift); OutStr[2]:=Hi(Shift); PositionRecord:=3;
    For i:=0 to PositionData do Begin OutStr[PositionRecord]:=Data[i]; inc(PositionRecord); End;
    Smeshen:=PositionRecord;
    DataTemp:=PositionCode;
    For i:=0 to PositionVarPoint-1 do
      Begin
        if PointVar[i].Length=0 Then
          Temp:=PointVar[i].PosPerexod-(PointVar[i].Position+Smeshen);
        if PointVar[i].Length=1 Then
          Temp:=PointVar[i].PosPerexod-PointVar[i].Position;
        PositionCode:=PointVar[i].Position;
        WriteInFile2(Lo(Temp),Hi(Temp));
      End;
    PositionCode:=DataTemp;
    For i:=0 to PositionCode do Begin OutStr[PositionRecord]:=Code[i]; inc(PositionRecord); End;
  End;

Begin
  ClrScr;
{  if ParamCount=1 then FileInput:=ParamStr(1) else Halt(1);}
  FileOutput:='OUTFILE.SWP';
  FileInput:='test1.prg';
  Initialization;

  Assign(DescriptFile,FileInput); {Загрузка анализируемого файла}
  Reset(DescriptFile,1);
  BlockRead(DescriptFile,InpStr,SizeOf(InpStr),SizeFile);
  Close(DescriptFile);

  Scaner;

  Assign(DescriptFile,FileOutput); {Запись полученного файла}
  Rewrite(DescriptFile,1);
  BlockWrite(DescriptFile,AnaStr,LengthFile,SizeFile);
{  BlockWrite(DescriptFile,OutStr,PositionRecord);}
  Close(DescriptFile);

{  WriteInFile2($32,$E4); {xor AH,AH}  {Установка видеорежима}
{  WriteInFile2($B0,$03); {mov AL,03h}
{  WriteInFile2($CD,$10); {int 10h}
  WriteInFile2($B4,$05); {mov AH,05} {Установка активной страницы}
  WriteInFile2($32,$C0); {xor AL,AL}
  WriteInFile2($CD,$10); {int 10h}

  CompilerProgr;
  For i:=1 to 10 do
    Begin
      Writeln('Имя=',VarMemory[i].NameVar,'  Указатель=',VarMemory[i].PointVar,
              '  Размер=',VarMemory[i].SizeVar,'  Тип переменной=',VarMemory[i].TypeVar,
              '  Арифметика=',VarMemory[i].Arifmetic);
    End;

  FormatingComFile;
  Assign(DescriptFile,'Otp.com'); {Запись полученного файла}
  Rewrite(DescriptFile,1);
{  BlockWrite(DescriptFile,AnaStr,LengthFile,SizeFile);}
  BlockWrite(DescriptFile,OutStr,PositionRecord);
  Close(DescriptFile);
  Repeat Until Keypressed;
End.